using System;
using System.Collections.Generic;
using System.Text;

namespace ClientTools.Client.Library.Provider
{
    public class WebserviceProvider: 
        Interfaces.IProvider,
        Interfaces.ILogging, 
        Interfaces.IStats, 
        Interfaces.IVersions,
        Interfaces.IPackager,
        Interfaces.IMedia 
    {

        private MaintenanceService.ClientToolsMaintenanceService _maintenanceService;
        private PackageService.ClientToolsPackageService _packageService;
        private MediaService.ClientToolsMediaService _mediaService;
        //private Med _packageService;
        private string _userName;
        private string _password;
        private string _serviceFolderUrl;

        public string ServiceFolderUrl
        {
            get { return _serviceFolderUrl; }
            set { this._serviceFolderUrl = value; }
        }

        public string UserName
        {
            get { return _userName; }
            set { _userName = value; }
        }

        public string Password
        {
            get { return _password; }
            set { _password = value; }
        }

        public WebserviceProvider()
        {
            this._maintenanceService = new ClientTools.Client.Library.MaintenanceService.ClientToolsMaintenanceService();
            this._packageService = new ClientTools.Client.Library.PackageService.ClientToolsPackageService();
            this._mediaService = new ClientTools.Client.Library.MediaService.ClientToolsMediaService();
        }

        public WebserviceProvider(string serviceFolderUrl, string userName, string password)
        {
            if (serviceFolderUrl.EndsWith("/"))
            { 
                this._serviceFolderUrl = serviceFolderUrl;
            }
            else
            {
                this._serviceFolderUrl = serviceFolderUrl + "/"; 
            }

            this._maintenanceService = new ClientTools.Client.Library.MaintenanceService.ClientToolsMaintenanceService();
            this._maintenanceService.Url = this._serviceFolderUrl + "ClientToolsMaintenanceService.asmx";
            this._packageService = new ClientTools.Client.Library.PackageService.ClientToolsPackageService();
            this._packageService.Url = this._serviceFolderUrl + "ClientToolsPackageService.asmx";
            this._mediaService = new ClientTools.Client.Library.MediaService.ClientToolsMediaService();
            this._mediaService.Url = this._serviceFolderUrl + "ClientToolsMediaService.asmx";

            this._userName = userName;
            this._password = password;
        }

#region Datatype Conversions

        private ClientTools.Library.Logging.LogInfoCollection ConvertLogInfos(MaintenanceService.LogInfo[] serviceLogInfos)
        {
            ClientTools.Library.Logging.LogInfoCollection returnValue = new ClientTools.Library.Logging.LogInfoCollection();
            foreach (MaintenanceService.LogInfo serviceLogInfo in serviceLogInfos)
            {
                ClientTools.Library.Logging.LogInfo loginfo = new ClientTools.Library.Logging.LogInfo();
                loginfo.Count = serviceLogInfo.Count;
                loginfo.LogHeader = serviceLogInfo.LogHeader;
                returnValue.Add(loginfo);
            }
            return returnValue;
        }

        private ClientTools.Library.Logging.LogCollection ConvertLogs(MaintenanceService.Log[] serviceLogs)
        {
            ClientTools.Library.Logging.LogCollection returnValue = new ClientTools.Library.Logging.LogCollection();
            foreach (MaintenanceService.Log serviceLog in serviceLogs)
            {
                ClientTools.Library.Logging.Log log = new ClientTools.Library.Logging.Log();
                log.DateStamp = serviceLog.DateStamp;
                log.ID = serviceLog.ID;
                log.LogComment = serviceLog.LogComment;
                log.LogHeader = serviceLog.LogHeader;
                log.NodeId = serviceLog.NodeId;
                log.UserId = serviceLog.UserId;
                returnValue.Add(log);
            }
            return returnValue;
        }

        private ClientTools.Library.Stats.StatsInfo ConvertStatsInfo(MaintenanceService.StatsInfo serviceStatsInfo)
        {
            ClientTools.Library.Stats.StatsInfo returnValue = new ClientTools.Library.Stats.StatsInfo();
            returnValue.Entries = serviceStatsInfo.Entries;
            returnValue.Sessions = serviceStatsInfo.Sessions;
            return returnValue;
        }

        private ClientTools.Library.Versions.VersionInfo ConvertVersionInfo(MaintenanceService.VersionInfo serviceVersionInfo)
        {
            ClientTools.Library.Versions.VersionInfo returnValue = new ClientTools.Library.Versions.VersionInfo();
            returnValue.Content = serviceVersionInfo.Content;
            returnValue.Documents = serviceVersionInfo.Documents;
            returnValue.PropertyData = serviceVersionInfo.PropertyData;
            returnValue.Versions = serviceVersionInfo.Versions;
            return returnValue;
        }

        private ClientTools.Library.Macros.MacroCollection ConvertMacroCollection(PackageService.Macro[] serviceMacros)
        {
            ClientTools.Library.Macros.MacroCollection returnValue = new ClientTools.Library.Macros.MacroCollection();
            foreach (PackageService.Macro serviceMacro in serviceMacros)
            {
                ClientTools.Library.Macros.Macro macro = new ClientTools.Library.Macros.Macro();
                macro.Alias = serviceMacro.Alias;
                macro.Assembly = serviceMacro.Assembly;
                macro.Id = serviceMacro.Id;
                macro.Name = serviceMacro.Name;
                macro.RefreshRate = serviceMacro.RefreshRate;
                macro.Type = serviceMacro.Type;
                macro.UseInEditor = serviceMacro.UseInEditor;
                macro.Xslt = serviceMacro.Xslt;
                macro.Properties = this.ConvertMacroPropertyCollection(serviceMacro.Properties);
                returnValue.Add(macro);
            }
            return returnValue;
        }

        private ClientTools.Library.Macros.MacroPropertyCollection ConvertMacroPropertyCollection(PackageService.MacroProperty[] serviceMacroProperties)
        {
            ClientTools.Library.Macros.MacroPropertyCollection returnValue = new ClientTools.Library.Macros.MacroPropertyCollection();
            foreach (PackageService.MacroProperty serviceMacroProperty in serviceMacroProperties)
            {
                ClientTools.Library.Macros.MacroProperty macroProperty = new ClientTools.Library.Macros.MacroProperty();
                macroProperty.Alias = serviceMacroProperty.Alias;
                macroProperty.Name = serviceMacroProperty.Name;
                macroProperty.Public = serviceMacroProperty.Public;
                macroProperty.SortOrder = serviceMacroProperty.SortOrder;
                macroProperty.Type = serviceMacroProperty.Type;
                returnValue.Add(macroProperty);
            }
            return returnValue;
        }

        private ClientTools.Library.DocumentTypes.DocumentTypeCollection ConvertDocumentTypeCollection(PackageService.DocumentType[] serviceDocumentTypes)
        {
            ClientTools.Library.DocumentTypes.DocumentTypeCollection returnValue = new ClientTools.Library.DocumentTypes.DocumentTypeCollection();
            foreach (PackageService.DocumentType serviceDocumentType in serviceDocumentTypes)
            {
                ClientTools.Library.DocumentTypes.DocumentType docType = new ClientTools.Library.DocumentTypes.DocumentType();
                docType.Alias = serviceDocumentType.Alias;
                foreach (string allowedDocumentType in serviceDocumentType.AllowedChilds)
                {
                    docType.AllowedChilds.Add(allowedDocumentType);
                }
                docType.DefaultTemplate = serviceDocumentType.DefaultTemplate;
                foreach (PackageService.GenericProperty serviceGenericProperty in serviceDocumentType.GenericProperties)
                {
                    ClientTools.Library.DocumentTypes.GenericProperty genericProperty = new ClientTools.Library.DocumentTypes.GenericProperty();
                    genericProperty.Alias = serviceGenericProperty.Alias;
                    genericProperty.Description = serviceGenericProperty.Description.Value;
                    genericProperty.Mandatory = serviceGenericProperty.Mandatory;
                    genericProperty.Name = serviceGenericProperty.Name;
                    genericProperty.Tab = serviceGenericProperty.Tab;
                    genericProperty.Type = serviceGenericProperty.Type;
                    genericProperty.Validation = serviceGenericProperty.Validation;
                    docType.GenericProperties.Add(genericProperty);
                }
                docType.Icon = serviceDocumentType.Icon;
                docType.Name = serviceDocumentType.Name;
                foreach (PackageService.Tab serviceTab in serviceDocumentType.Tabs)
                {
                    ClientTools.Library.DocumentTypes.Tab tab = new ClientTools.Library.DocumentTypes.Tab();
                    tab.Caption = serviceTab.Caption;
                    tab.Id = serviceTab.Id;
                    docType.Tabs.Add(tab);
                }
                foreach (string template in serviceDocumentType.Templates)
                {
                    docType.Templates.Add(template);
                }
                docType.Thumbnail = serviceDocumentType.Thumbnail;
                returnValue.Add(docType);
            }
            return returnValue;
        }

        private ClientTools.Library.Templates.TemplateCollection ConvertTemplateCollection(PackageService.Template[] serviceTemplates)
        {
            ClientTools.Library.Templates.TemplateCollection returnValue = new ClientTools.Library.Templates.TemplateCollection();
            foreach (PackageService.Template serviceTemplate in serviceTemplates)
            {
                ClientTools.Library.Templates.Template template = new ClientTools.Library.Templates.Template();
                template.Alias = serviceTemplate.Alias;
                template.Design = serviceTemplate.Design;
                template.MasterTemplate = serviceTemplate.MasterTemplate;
                template.Name = serviceTemplate.Name;
                returnValue.Add(template);
            }
            return returnValue;
        }

        private ClientTools.Library.Media.MediaCollection ConvertMediaCollection(MediaService.Media[] serviceMedias)
        {
            ClientTools.Library.Media.MediaCollection returnValue = new ClientTools.Library.Media.MediaCollection();
            foreach (MediaService.Media serviceMedia in serviceMedias)
            {
                returnValue.Add(this.ConvertMedia(serviceMedia));
            }
            return returnValue;
        }

        private ClientTools.Library.Media.Media ConvertMedia(MediaService.Media serviceMedia)
        { 
            ClientTools.Library.Media.Media media = new ClientTools.Library.Media.Media()
            {
                Id = serviceMedia.Id,
                Name = serviceMedia.Name,
                NodeTypeAlias = serviceMedia.NodeTypeAlias,
                NodeTypeId = serviceMedia.NodeTypeId
            };
            foreach (MediaService.Property umbracoProperty in serviceMedia.Properties)
            {
                ClientTools.Library.Media.Property property = new ClientTools.Library.Media.Property()
                {
                    Id = umbracoProperty.Id,
                    PropertyTypeAlias = umbracoProperty.PropertyTypeAlias,
                    PropertyTypeId = umbracoProperty.PropertyTypeId,
                    Value = umbracoProperty.Value 
                };
                media.Properties.Add(property);
            }
            foreach (MediaService.Media serviceChildMedia in serviceMedia.Children)
            {
                media.Children.Add(this.ConvertMedia(serviceChildMedia));
            }
            return media;
        }

#endregion

#region I_Logging Member

        public ClientTools.Library.Logging.LogInfoCollection GetLogInfos()
        {
            return this.ConvertLogInfos(this._maintenanceService.GetLogInfos(_userName, _password));
        }

        public ClientTools.Library.Logging.LogCollection GetLogs(DateTime? startDate, DateTime? endDate, string logHeader, int? userId, int? nodeId, int? maxRows, string comment)
        {
            return this.ConvertLogs(this._maintenanceService.GetLogs(_userName, _password, startDate, endDate, logHeader, userId, nodeId, maxRows, comment));
        }

        public int DeleteLogsByIDs(int[] logIds)
        {
            return this._maintenanceService.DeleteLogsById(_userName, _password, logIds);
        }

        public int DeleteLogsByHeader(string logHeader)
        {
            return this._maintenanceService.DeleteLogsByHeader(_userName, _password, logHeader);
        }

        public int DeleteLogsByDate(DateTime date)
        {
            return this._maintenanceService.DeleteLogsByDate(_userName, _password, date);
        }

#endregion

#region I_Stats Member

        ClientTools.Library.Stats.StatsInfo ClientTools.Client.Library.Interfaces.IStats.DeleteStatsByDate(DateTime date)
        {
            return this.ConvertStatsInfo(this._maintenanceService.DeleteStatsByDate(this._userName, this._password, date));
        }

        ClientTools.Library.Stats.StatsInfo ClientTools.Client.Library.Interfaces.IStats.GetStatsInfo()
        {
            return this.ConvertStatsInfo(this._maintenanceService.GetStatsInfo(this._userName, this._password));
        }

#endregion

#region I_Versions Member

        public ClientTools.Library.Versions.VersionInfo GetVersionInfos()
        {
            return this.ConvertVersionInfo(this._maintenanceService.GetVersionInfos(this._userName, this._password));
        }

        public ClientTools.Library.Versions.VersionInfo DeleteVersionsByDate(DateTime date)
        {
            return this.ConvertVersionInfo(this._maintenanceService.DeleteVersionsByDate(this._userName, this._password, date));
        }

        public ClientTools.Library.Versions.VersionInfo DeleteVersionsByNumberOfItems(int numberOfItems)
        {
            return this.ConvertVersionInfo(this._maintenanceService.DeleteVersionsByNumberOfItems(this._userName, this._password, numberOfItems));
        }

        public ClientTools.Library.Versions.ContentNodeCollection GetNodes(int parentId, bool recursive)
        {
            throw new NotImplementedException();
        }


#endregion

#region I_Provider Member

        public string Providername
        {
            get { return "Webservice Provider"; }
        }

#endregion

#region IPackager Member

        public ClientTools.Library.Macros.MacroCollection GetMacros()
        {
            return this.ConvertMacroCollection(this._packageService.GetMacros(this._userName, this._password));
        }

        public ClientTools.Library.Templates.TemplateCollection GetTemplates()
        {
            return this.ConvertTemplateCollection(this._packageService.GetTemplates(this._userName, this._password));
        }

        public ClientTools.Library.DocumentTypes.DocumentTypeCollection GetDocumentTypes()
        {
            return this.ConvertDocumentTypeCollection(this._packageService.GetDocumentTypes(this._userName, this._password));
        }

#endregion


        #region IMedia Members

        public ClientTools.Library.Media.MediaCollection GetRootMedias(bool recursive)
        {
            return this.ConvertMediaCollection(this._mediaService.GetRootMedias(this._userName, this._password, recursive));
        }

        public ClientTools.Library.Media.MediaCollection GetMedias(int parentId, bool recursive)
        {
            throw new NotImplementedException();
        }

        bool ClientTools.Client.Library.Interfaces.IMedia.DeleteMedia(int mediaId)
        {
            return this._mediaService.DeleteMedia(_userName, _password, mediaId);
        }

        public ClientTools.Library.Media.Media CreateImage(int parentId, string fileName, byte[] content)
        {
            return this.ConvertMedia(this._mediaService.CreateImage(_userName, _password, parentId, fileName, content));
        }

        public ClientTools.Library.Media.Media CreateFile(int parentId, string fileName, byte[] content)
        {
            return this.ConvertMedia(this._mediaService.CreateFile(_userName, _password, parentId, fileName, content));
        }

        public ClientTools.Library.Media.Media CreateFolder(int parentId, string folderName)
        {
            return this.ConvertMedia(this._mediaService.CreateFolder(_userName, _password, parentId, folderName));
        }

        #endregion

    }
}
